package com.atguigu.hashtab;

/**
 * @author durant
 * @create 2021-11-16 15:22
 */
public class HashTabDemo {
    public static void main(String[] args) {
        HashTab hashTab = new HashTab(7);
        Emp emp1 = new Emp(1, "jack");
        Emp emp2 = new Emp(2, "jack2");
        Emp emp3 = new Emp(6, "jack6");
        Emp emp4 = new Emp(4, "jack4");
        Emp emp8 = new Emp(8, "jack4");
        hashTab.add(emp1);
        hashTab.add(emp2);
        hashTab.add(emp3);
        hashTab.add(emp4);
        hashTab.add(emp8);
        hashTab.list();
//        Emp emp = hashTab.selectById(3);
//        System.out.println(emp);
        System.out.println("删除过后的list");
        hashTab.deleteById(6);
        hashTab.list();

    }

}

class HashTab { // 管理多条链表
    private EmpLinkedList[] empLinkedListArray;
    private int size;

    // 构造器
    public HashTab(int size) {
        // 初始化empLinkedListArray
        empLinkedListArray = new EmpLinkedList[size];
        this.size = size;
        //TODO 留了一个坑
        // 创建链表集合后，集合中的链表并没有进行初始化，其值均为空，所以会报错
        for (int i = 0; i < empLinkedListArray.length; i++) {
            empLinkedListArray[i] = new EmpLinkedList();
        }

    }

    // 添加雇员
    public void add(Emp emp) {
        // 根据员工的id来得到这个员工应该加入到哪个链表中
        int empLinkedListNo = hashFun(emp.id);
        // 将emp加入到应该添加的链表中
        empLinkedListArray[empLinkedListNo].add(emp);


    }

    // 编写散列函数，使用一个简单取模法
    public int hashFun(int id) {
        return id % size;

    }

    // 遍历所有的链表
    public void list() {
        for (int i = 0; i < size; i++) {
            empLinkedListArray[i].list(i);

        }
    }

    // 查找雇员
    public Emp selectById(int id) {
        // 取模，确定是在哪一条链表上
        int empLinkedListNo = hashFun(id);
        Emp emp = empLinkedListArray[empLinkedListNo].selectById(id);
        return emp;
    }

    // 查找雇员
    public void deleteById(int id) {
        // 取模，确定是在哪一条链表上
        int empLinkedListNo = hashFun(id);
        empLinkedListArray[empLinkedListNo].deleteById(id);

    }


}

// 表示一个雇员
class Emp {
    public int id;
    public String name;
    public Emp next;

    @Override
    public String toString() {
        return "Emp{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public Emp() {
    }


    public Emp(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

// 创建emplinkedlist， 表示链表
class EmpLinkedList {

    // 头指针，执行第一个emp，因为是链表的头，所以指向第一个链表
    private Emp head; // 默认为null

    // 添加雇员
    // 1.假定，当添加雇员时，id是自增长的，
    public void add(Emp emp) {
        // 如果是添加第一个成员
        if (head == null) {
            head = emp;
            return;
        }
        // 如果不是第一个雇员，则使用一个辅助指针，帮助定位到最后
        Emp curEmp = head;
        while (true) {
            if (curEmp.next == null) {//即定位完成
                break;
            }
            curEmp = curEmp.next; // 后移
        }
        // 退出时直接将emp加入链表
        curEmp.next = emp;
    }

    // 遍历链表的雇员信息
    public void list(int no) {
        if (head == null) {// 为空
//            System.out.println("第" + no + "条链表为空");
            return;
        }
        Emp curEmp = head;
        while (true) {
            System.out.print("id=" + curEmp.id + ",name=" + curEmp.name + " ");
            if (curEmp.next == null) {// 说明已经是最后节点
                break;
            }
            curEmp = curEmp.next;

        }
        System.out.println();// 这一个链表遍历结束后换行
    }

    public Emp selectById(int id) {
        if (head == null) {
            System.out.println("链表为空，没有包含元素");
            return null;
        }
        Emp temp = head;
        while (true) {
            if (temp.id == id) {
                break;
            }
            if (temp.next == null) {// 当走到这一步时，表示没有找到指定的id，因此将temp置为空，并且退出while循环
                temp = null;
                break;
            }
            temp = temp.next;
        }
        return temp;
    }

    public void deleteById(int id) {
        if (head == null) {
            System.out.println("链表为空，没有包含要删除的元素");
        }
        Emp temp = head;
        while (true) {
            if (head.id == id) {// 如果需要删除的是head，那么直接让下一个来当头，如果没有下一个，直接置为空
                if (head.next != null) {
                    head = head.next;
                } else {
                    head = null;
                }
                break;
            }
            if (temp.next.id == id) {// 进行删除操作，即next置为空，或者指向下一个emp
                if (temp.next.next == null) {
                    temp.next = null;
                } else {
                    temp.next = temp.next.next; // 当需要删除temp.next 时，只需要将next指向next的next即可
                }
                break;
            }
            if (temp.next.next == null) {// 当走到这一步时，表示没有找到指定的id，因此将temp置为空，并且退出while循环
                break;
            }
            temp = temp.next;
        }

    }
}